package com.tanhua.dubbo.api;

import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@DubboService
public class CommentApiImpl implements CommentApi {

    @Autowired
    private MongoTemplate mongoTemplate;


    /**
     * 分页查询评论列表
     *
     * @param movementId
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageResult<Comment> pageCommentList(String movementId, Long page, Long pageSize) {
        Query query = new Query(Criteria.where("publishId").is(new ObjectId(movementId))
                .and("commentType").is(CommentType.COMMENT.getType())
        );
        long count = mongoTemplate.count(query, Comment.class);
        long start = (page - 1) * pageSize;
        List<Comment> comments = new ArrayList<>();
        if (count > start) {
            query.skip(start).limit(pageSize.intValue());
            query.with(Sort.by(Sort.Direction.DESC, "created"));
            comments = mongoTemplate.find(query, Comment.class);
        }
        return new PageResult(page, pageSize, count, comments);
    }

    /**
     * 添加点赞 评论 点赞
     *
     * @param comment
     */
    @Override
    public Integer publish(Comment comment) {
        Query commentQuery = new Query(Criteria.where("publishId").is(comment.getPublishId())
                .and("commentType").is(comment.getCommentType())
                .and("userId").is(comment.getUserId()));
        long count = mongoTemplate.count(commentQuery, Comment.class);
        if(count > 0) {
            Movement movement = mongoTemplate.findById(comment.getPublishId(), Movement.class);
            return movement.statisCount(comment.getCommentType());
        }

        Movement movement = mongoTemplate.findById(comment.getPublishId(), Movement.class);
        comment.setPublishUserId(movement.getUserId());
        comment.setCreated(System.currentTimeMillis());
        mongoTemplate.insert(comment);

        Query query = new Query(Criteria.where("_id").is(movement.getId()));
        Update update = new Update();
        update.inc(getCollName(comment.getCommentType()), 1);
        FindAndModifyOptions famo = new FindAndModifyOptions();
        // 需要返回最新值
        famo.returnNew(true);
        movement = mongoTemplate.findAndModify(query, update, famo, Movement.class);
        return movement.statisCount(comment.getCommentType());
    }

    /**
     * 删除点赞 评论 喜欢
     * @param comment
     * @return
     */
    @Override
    public Integer remove(Comment comment) {
        Query query = new Query(
                Criteria.where("publishId").is(comment.getPublishId())
                        .and("userId").is(comment.getUserId())
                        .and("commentType").is(comment.getCommentType())
        );
        mongoTemplate.remove(query, Comment.class);

        //修改动态表中的数量
        Query movementQuery = new Query(Criteria.where("_id").is(comment.getPublishId()));
        Update update = new Update();
        update.inc(getCollName(comment.getCommentType()), -1);
        FindAndModifyOptions famo = new FindAndModifyOptions();
        famo.returnNew(true);
        Movement movement = mongoTemplate.findAndModify(movementQuery, update, famo, Movement.class);
        return movement.statisCount(comment.getCommentType());
    }

    /**
     * 根据评论类型获取列名
     * @param commentType
     * @return
     */
    private String getCollName(int commentType) {
        if(commentType == CommentType.LIKE.getType()) {
            return "likeCount";
        }else if(commentType == CommentType.COMMENT.getType()) {
            return "commentCount";
        }else {
            return "loveCount";
        }
    }

    /**
     * 动态中用户是否点赞
     *
     * @param visitorId
     * @param movementIds
     * @return
     */
    @Override
    public Map<ObjectId, Boolean> findLikeInMovements(Long visitorId, List<ObjectId> movementIds) {
        Query query = new Query(Criteria.where("userId").is(visitorId)
                .and("publishId").in(movementIds)
                .and("commentType").is(CommentType.LIKE.getType()));
        List<Comment> comments = mongoTemplate.find(query, Comment.class);
        Map<ObjectId, Boolean> resultMap = new HashMap<>();
        for (Comment comment : comments) {
            resultMap.put(comment.getPublishId(), true);
        }
        return resultMap;
    }

    /**
     * 动态中用户是否喜欢
     *
     * @param visitorId
     * @param movementIds
     * @return
     */
    @Override
    public Map<ObjectId, Boolean> findLoveInMovements(Long visitorId, List<ObjectId> movementIds) {
        Query query = new Query(Criteria.where("userId").is(visitorId)
                .and("publishId").in(movementIds)
                .and("commentType").is(CommentType.LOVE.getType()));
        List<Comment> comments = mongoTemplate.find(query, Comment.class);
        Map<ObjectId, Boolean> resultMap = new HashMap<>();
        for (Comment comment : comments) {
            resultMap.put(comment.getPublishId(), true);
        }
        return resultMap;
    }

    /**
     * 查询点赞数量
     *
     * @param id
     * @return
     */
    @Override
    public Integer findLikeCount(String id) {
        Query query = new Query(Criteria.where("publishId").is(new ObjectId(id))
                .and("commentType").is(CommentType.LIKE.getType()));
        long count = mongoTemplate.count(query, Comment.class);
        return (int)count;
    }

    /**
     * 查询评论数量
     *
     * @param id
     * @return
     */
    @Override
    public Integer findCommentCount(String id) {
        Query query = new Query(Criteria.where("publishId").is(new ObjectId(id))
                .and("commentType").is(CommentType.COMMENT.getType()));
        long count = mongoTemplate.count(query, Comment.class);
        return (int)count;
    }
}
